﻿
using Dora.Orm.SqlSugarCore.UnitOfWork;
using Dora.Services.AdminUser.Dto.QueryDto;
using Dora.Services.AdminUser.Entities;
using Dora.Services.AdminUser.IApplication;
using Dora.Services.AdminUser.Repository.Repositorys;
using Dora.Tools.Utility.Const;
using Microsoft.Extensions.Logging;
using Surging.Core.Common;
using Surging.Core.CPlatform.Ioc;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Dora.Services.AdminUser.Application.Base;
using Dora.Services.AdminUser.Dto.SaveDto;
using Dora.Services.AdminUser.Dto.ViewDto;
using Dora.Tools.Enums.AdminUser;
using Dora.Tools.Enums;

namespace Dora.Services.AdminUser.Application
{
    /// <summary>
    /// 角色表服务
    /// </summary>
    [ModuleName(DoraModuleName.AdminUser)]
    public class RoleService : DoraServiceBase, IRoleService
    {
        
        private ISugarUnitOfWork _unitOfWork;
        private readonly RoleRepository _repository;
        private readonly RolePermissionMapRepository _rolePermissionMapRepository;
        private readonly SystemInfoRepository _systemInfoRepository;
        private readonly PermissionRepository _permissionRepository;
        private readonly DoraUserRoleMapRepository _doraUserRoleMapRepository;
        public RoleService(ISugarUnitOfWork unitOfWork)
        {
            _unitOfWork = unitOfWork;
            _repository = new RoleRepository(unitOfWork);
            _rolePermissionMapRepository = new RolePermissionMapRepository(unitOfWork);
            _systemInfoRepository = new SystemInfoRepository(unitOfWork);
            _permissionRepository = new PermissionRepository(unitOfWork);
            _doraUserRoleMapRepository = new DoraUserRoleMapRepository(unitOfWork);
        }


        /// <summary>
        /// 创建
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        public async Task<ResultDto<RoleEntity>> Create(RoleEntity entity)
        {
            try
            {
                if (string.IsNullOrWhiteSpace(entity.Name))
                {
                    return ResultDto<RoleEntity>.Error("请输入角色名称");
                }

                var system = await _systemInfoRepository.FirstOrDefaultAsync(entity.SystemId);
                if (system == null)
                {
                    return ResultDto<RoleEntity>.Error("请选择系统");
                }
                entity.SystemId = system.Id;
                entity.SystemKey = system.SystemKey;

                if (!string.IsNullOrWhiteSpace(entity.RoleNO))
                {
                    var existRoleNO = await _repository.ExistRoleNO(entity.Id, entity.RoleNO.Trim());
                    if (existRoleNO)
                    {
                        return ResultDto<RoleEntity>.Error("角色编号已经存在");
                    }
                    entity.RoleNO = entity.RoleNO.Trim();
                }

                entity.CreatedTime = DateTime.Now;
                entity.UpdatedTime = DateTime.Now;
                var result = await _repository.InsertAsync(entity);
                if (result != null)
                {
                    return ResultDto<RoleEntity>.Success(result);
                }
                else
                {
                    return ResultDto<RoleEntity>.Error("创建失败");
                }
            }
            catch (Exception ex)
            {

                throw;
            }
        }


        /// <summary>
        /// 根据Id获取一个实体对象
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public async Task<RoleEntity> GetById(Guid id)
        {
            return await _repository.FirstOrDefaultAsync(id);
        }


        /// <summary>
        /// 分页获取数据
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<PageDataList<RoleViewDto>> GetPageList(RoleQueryDto input)
        {
            var page = await _repository.GetPageList(input);
            return page;
        }


        /// <summary>
        /// 修改
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        public async Task<ResultDto> Update(RoleEntity entity)
        {
            if (string.IsNullOrWhiteSpace(entity.Name))
            {
                return ResultDto.Error("请输入角色名称");
            }

            if (!string.IsNullOrWhiteSpace(entity.RoleNO))
            {
                var existRoleNO = await _repository.ExistRoleNO(entity.Id, entity.RoleNO.Trim());
                if (existRoleNO)
                {
                    return ResultDto.Error("角色编号已经存在");
                }
                entity.RoleNO = entity.RoleNO.Trim();
            }
            entity.UpdatedTime = DateTime.Now;
            var result= await _repository.Update(entity);
            if (result)
            {
                return ResultDto.Success("修改成功");
            }
            else
            {
                return ResultDto.Error("修改失败");
            }
        }

        /// <summary>
        /// 根据IdList获取列表
        /// </summary>
        /// <param name="idList"></param>
        /// <returns></returns>
        public async Task<List<RoleEntity>> GetList(List<Guid> idList)
        {
            if (idList == null || idList.Count == 0)
            {
                return new List<RoleEntity>();
            }
            var list =await _repository.GetAllListAsync(it => idList.Contains(it.Id));
            return list;
        }

        /// <summary>
        /// 获取所有
        /// </summary>
        /// <returns></returns>
        public async Task<List<RoleEntity>> GetAll()
        {
            var list =await _repository.GetAllListAsync();
            return list;
        }
        
        /// <summary>
        /// 保存角色权限
        /// </summary>
        /// <returns></returns>
        public async Task<int> SaveRolePermission(RolePermissionSaveDto input)
        {
            //HashSet<EmployeeRolePermission> hs = new HashSet<EmployeeRolePermission>(list);
            //list = new List<EmployeeRolePermission>(hs);
            if (input == null || input.SystemId == 0|| input.RoleId == Guid.Empty)
            {
                return 0;
            }

            try
            {
                var systemPermissionList = await _permissionRepository.GetAllListAsync(it => it.SystemId == input.SystemId);
                var newList = new List<RolePermissionMapEntity>();
                if (input.PermissionIdList?.Count > 0)
                {
                    var permissionIdHash = input.PermissionIdList.ToHashSet();
                    foreach (var item in permissionIdHash)
                    {
                        newList.Add(new RolePermissionMapEntity() { RoleId = input.RoleId, PermissionId = item });
                    }
                }

                //var roleIdList = newList.Select(p => p.RoleId).Distinct().ToList();
                if (systemPermissionList?.Count > 0)
                {
                    var systemPermissionIdList = systemPermissionList.Select(p => p.Id).ToList();
                    await _rolePermissionMapRepository.DeleteByRoleIdAndPermissionIdList(input.RoleId, systemPermissionIdList);
                }

                if (newList.Count > 0)
                {
                    return await _rolePermissionMapRepository.CreateRange(newList);
                }
                else
                {
                    return 1;
                }
            }
            catch(Exception ex)
            {

            }
            return 0;
        }

        public async Task<ResultDto<bool>> Delete(RoleEntity entity)
        {
            var usedList = await _doraUserRoleMapRepository.GetDoraListByRoleIdList(new List<Guid>() {  entity.Id});

            if (usedList?.Count > 0)
            {
                var realNameList = usedList.Select(p => p.RealName);
                var realNames = string.Join(',', realNameList.ToArray());
                return new ResultDto<bool>(ResultCode.Fail, $"角色被下列用户使用[{realNames}]，不能被删除", false);
            }
            entity.UpdatedTime = DateTime.Now;
            var result = await _repository.Delete(entity.Id);
            return new ResultDto<bool>(ResultCode.Success, result ? "删除成功" : "删除失败", result);
        }

        public async Task<RoleEntity> GetByRoleNo(string roleNo)
        {
            return await _repository.GetByRoleNo(roleNo);
        }

        public async Task<bool> BatchDisable(List<Guid> listIds, string updatedUserName, Guid updatedUserId)
        {
            try
            {
                return await _repository.BatchDisable(listIds, updatedUserName, updatedUserId);

            }
            catch (Exception ex)
            {

                throw;
            }
        }

        public async Task<bool> BatchEnable(List<Guid> listIds, string updatedUserName, Guid updatedUserId)
        {
            try
            {
                return await _repository.BatchEnable(listIds, updatedUserName, updatedUserId);

            }
            catch (Exception ex)
            {

                throw;
            }
        }

        public async Task<List<RoleEntity>> GetDoraAuthedList(Guid userId)
        {
            return await _repository.GetDoraAuthedList(userId);
        }

        public async Task<List<RoleEntity>> GetCreatedList(Guid userId)
        {
            return await _repository.GetCreatedList(userId,null);
        }

        public async Task<List<RoleEntity>> GetDoraAuthedAndCreatedList(Guid userId)
        {
            var list = await _repository.GetDoraAuthedList(userId);
            if (list == null)
            {
                list = new List<RoleEntity>();
            }
            var listCreated = await _repository.GetCreatedList(userId,null);
            if (listCreated?.Count > 0)
            {
                foreach (var item in listCreated)
                {
                    var exitItem = list.Exists(p => p.Id == item.Id);
                    if (exitItem == false)
                    {
                        list.Add(item);
                    }
                }
            }
            return list;
        }

        /// <summary>
        /// 根据系统Key获取列表
        /// </summary>
        /// <param name="systemKey"></param>
        /// <returns></returns>
        public async Task<List<RoleEntity>> GetListBySystemKey(string systemKey)
        {
            if (string.IsNullOrEmpty(systemKey))
            {
                return new List<RoleEntity>();
            }
            var list =await _repository.GetAllListAsync(it => it.SystemKey== systemKey&&it.IsDeleted==0);
            return list;
        }
        

        /// <summary>
        /// 角色编号是否存在
        /// </summary>
        /// <returns></returns>
        public async Task<bool> ExistRoleNO(Guid id, string roleNO)
        {
            return await _unitOfWork.QueryClient.Queryable<RoleEntity>().Where(it => it.RoleNO == roleNO && it.IsDeleted == 0 && it.Id != id).CountAsync() > 0;
        }

        /// <summary>
        /// 获取某个系统的所有权限，如果RoleId不为empty,并且把这个角色在这个系统拥有的权限打上标记
        /// </summary>
        /// <param name="roleId"></param>
        /// <returns></returns>
        public async Task<PermissionsWithTreeDto> GetPermissionsWithTreeByRoleId(Guid roleId)
        {
            var result = new PermissionsWithTreeDto();
            var roleEntity =await _repository.FirstOrDefaultAsync(roleId);
            if (roleEntity == null)
            {
                return result;
            }

            var permissionListAll = new List<PermissionListDto>();
            if (roleEntity.SystemId == (int)DoraSysIdentifier.TAS && roleEntity.OrgType != (int)PermissionOrgType.Common)
            {
                permissionListAll = await _permissionRepository.GetListBySystemIdListAndOrgType(new List<int>() { roleEntity.SystemId }, (PermissionOrgType)roleEntity.OrgType);
            }
            else
            {
                permissionListAll = await _permissionRepository.GetListBySystemIdList(new List<int>() { roleEntity.SystemId });
            }

            if (permissionListAll == null||permissionListAll.Count==0)
            {
                return result;
            }

            var moduleList = permissionListAll.Where(it=>it.PType==(int)PermissionType.Module).ToList();
            if (moduleList?.Count > 0)
            {
                #region 给角色拥有的权限打上标识
                var selectedList = await _permissionRepository.GetByRoleId(roleId);
                if (selectedList?.Count > 0)
                {
                    result.SelectedIdList = selectedList.Where(p => p.HasSub == 0).Select(p => p.Id).ToList();
                    result.SelectedAuthKeyList = selectedList.Where(p => p.HasSub == 0).Select(p => p.AuthKey).ToList();
                    foreach (var item in permissionListAll)
                    {
                        var selectedItem = selectedList.Find(p => p.Id == item.Id);
                        item.IsSelected = false;
                        if (selectedItem != null)
                        {
                            item.IsSelected = true;
                        }
                    }
                }
                #endregion

                foreach (var module in moduleList)
                {
                    if (permissionListAll.Count > 0)
                    {
                        var subListMenu = permissionListAll.FindAll(p => p.ParentId == module.Id && p.PType == (int)PermissionType.Menu);//菜单List
                        if (subListMenu?.Count > 0)
                        {
                            //if (subListMenu.Any(p => p.IsSelected))
                            //{
                            //    module.IsSelected = true;
                            //}
                            module.SubList = subListMenu;
                            foreach (var item in subListMenu)
                            {
                                var subLists = permissionListAll.FindAll(p => p.ParentId == item.Id);//菜单下的权限列表
                                item.SubList = subLists;
                            }
                        }
                    }
                }
            }
            result.PermissionList = moduleList;
            return result;
        }

        /// <summary>
        /// 获取某个系统的所有权限，如果RoleId不为empty,并且把这个角色在这个系统拥有的权限打上标记
        /// </summary>
        /// <param name="roleId"></param>
        /// <returns></returns>
        public async Task<PermissionsWithTreeDto> GetPermissionsWithTreeByRoleIdAndOrgType(Guid roleId,PermissionOrgType orgType)
        {
            var result = new PermissionsWithTreeDto();
            var roleEntity = await _repository.FirstOrDefaultAsync(roleId);
            if (roleEntity == null)
            {
                return result;
            }

            var permissionListAll = await _permissionRepository.GetListBySystemIdListAndOrgType(new List<int>() { roleEntity.SystemId }, orgType);
            if (permissionListAll == null || permissionListAll.Count == 0)
            {
                return result;
            }

            var moduleList = permissionListAll.Where(it => it.PType == (int)PermissionType.Module).ToList();
            if (moduleList?.Count > 0)
            {
                #region 给角色拥有的权限打上标识
                var selectedList = await _permissionRepository.GetByRoleId(roleId);
                if (selectedList?.Count > 0)
                {
                    result.SelectedIdList = selectedList.Where(p => p.HasSub == 0).Select(p => p.Id).ToList();
                    result.SelectedAuthKeyList = selectedList.Where(p => p.HasSub == 0).Select(p => p.AuthKey).ToList();
                    foreach (var item in permissionListAll)
                    {
                        var selectedItem = selectedList.Find(p => p.Id == item.Id);
                        item.IsSelected = false;
                        if (selectedItem != null)
                        {
                            item.IsSelected = true;
                        }
                    }
                }
                #endregion

                foreach (var module in moduleList)
                {
                    if (permissionListAll.Count > 0)
                    {
                        var subListMenu = permissionListAll.FindAll(p => p.ParentId == module.Id && p.PType == (int)PermissionType.Menu);//菜单List
                        if (subListMenu?.Count > 0)
                        {
                            //if (subListMenu.Any(p => p.IsSelected))
                            //{
                            //    module.IsSelected = true;
                            //}
                            module.SubList = subListMenu;
                            foreach (var item in subListMenu)
                            {
                                var subLists = permissionListAll.FindAll(p => p.ParentId == item.Id);//菜单下的权限列表
                                item.SubList = subLists;
                            }
                        }
                    }
                }
            }
            result.PermissionList = moduleList;
            return result;
        }

        /// <summary>
        /// 获取用户在某个机构下所拥有或创建的角色
        /// </summary>
        /// <param name="userId"></param>
        /// <param name="orgId"></param>
        /// <returns></returns>
        public async Task<List<RoleEntity>> GetTasAuthedAndCreatedList(Guid userId,int orgId)
        {
            var list = await _repository.GetTasAuthedList(userId, orgId);
            if (list == null)
            {
                list = new List<RoleEntity>();
            }
            var listCreated = await _repository.GetCreatedList(userId,orgId);
            if (listCreated?.Count > 0)
            {
                foreach (var item in listCreated)
                {
                    var exitItem = list.Exists(p => p.Id == item.Id);
                    if (exitItem == false)
                    {
                        list.Add(item);
                    }
                }
            }
            return list;
        }

        /// <summary>
        /// 获取用户在某个机构下所拥有的角色
        /// </summary>
        /// <param name="userId"></param>
        /// <param name="orgId"></param>
        /// <returns></returns>
        public async Task<List<RoleEntity>> GetTasAuthedList(Guid userId, int orgId)
        {
            var list = await _repository.GetTasAuthedList(userId, orgId);
            return list;
        }

        /// <summary>
        /// 根据系统Key和组织机构Id获取列表
        /// </summary>
        /// <param name="systemKey"></param>
        /// <param name="orgId"></param>
        /// <returns></returns>
        public async Task<List<RoleEntity>> GetListBySystemKeyAndOrgId(string systemKey,int orgId)
        {
            if (string.IsNullOrEmpty(systemKey))
            {
                return new List<RoleEntity>();
            }
            var list = await _repository.GetAllListAsync(it => it.SystemKey == systemKey && it.OrgId == orgId && it.IsEnabled == 1 && it.IsDeleted == 0);
            return list;
        }

        /// <summary>
        /// 根据系统Key,组织机构Id和权限组织机构类型获取列表
        /// </summary>
        /// <param name="systemKey"></param>
        /// <param name="orgId"></param>
        /// <returns></returns>
        public async Task<List<RoleEntity>> GetListBySystemKeyOrgIdAndOrgType(string systemKey, int orgId, PermissionOrgType orgType)
        {
            if (string.IsNullOrEmpty(systemKey))
            {
                return new List<RoleEntity>();
            }
            var list = await _repository.GetAllListAsync(it => it.SystemKey == systemKey && it.OrgId == orgId && it.OrgType == (int)orgType && it.IsEnabled == 1 && it.IsDeleted == 0);
            return list;
        }
    }
}
